package com.zhangfb95.crosschain.infra.controller.advice;

import com.zhangfb95.crosschain.infra.exception.BusinessException;
import com.zhangfb95.crosschain.infra.model.Result;
import com.zhangfb95.crosschain.infra.statuscode.StatusCode;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * 统一异常处理器
 *
 * @author zhangfubing
 * @since 2020/7/2
 */
@Slf4j
@ControllerAdvice
public class DefaultExceptionHandler {

    /**
     * 业务异常
     *
     * @param e 异常对象
     * @return 接口返回对象
     */
    @ExceptionHandler(BusinessException.class)
    @ResponseBody
    public Result<Object> handle(BusinessException e) {
        return Result.fail(e.getCode(), e.getMessage(), e.getData());
    }

    /**
     * 非预期异常
     *
     * @param e 异常对象
     * @return 接口返回对象
     */
    @ExceptionHandler(Throwable.class)
    @ResponseBody
    public Result<Void> handle(Throwable e) {
        log.error(e.toString(), e);
        return Result.fail(StatusCode.COMMON_ERROR.getCode(), getStackTrace(e));
    }

    /**
     * 获取异常对象的堆栈信息
     *
     * @param throwable 异常对象
     * @return 堆栈信息字符串
     */
    public static String getStackTrace(Throwable throwable) {
        StringWriter sw = new StringWriter();
        try (PrintWriter pw = new PrintWriter(sw)) {
            throwable.printStackTrace(pw);
            return sw.toString();
        }
    }
}
